<template>
  <div class="chat-container">
    <!-- 1. 左侧区域（预留，原HTML结构保留） -->
    <div class="left">
      <div class="left-content">智慧社区助手导航区（可扩展）</div>
    </div>

    <!-- 2. 右侧聊天窗口 -->
    <div class="right">
      <!-- 聊天窗口主体（可拖动） -->
      <div 
        ref="chatWindowRef" 
        class="chat-main" 
        @mousedown="startDrag"
      >
        <!-- 2.1 模拟对话框（Element Plus Dialog） -->
        <el-dialog
          v-model="showSimDialog"
          title="模拟服务端消息"
          width="400px"
          @close="resetSimInput"
        >
          <el-input
            v-model="simInput"
            type="textarea"
            placeholder="请输入模拟服务端消息，按Enter发送（Shift+Enter换行）"
            @keydown="(e) => handleEnterKey(e, 'sim')"
            rows="5"
          />
          <template #footer>
            <el-button @click="handleSimSubmit">提交</el-button>
            <el-button @click="showSimDialog = false">关闭</el-button>
          </template>
        </el-dialog>

        <!-- 2.2 聊天头部 -->
        <div class="chat-header">
          <el-button 
            type="text" 
            icon="Close" 
            class="close-btn" 
            @click="closeChat"
          />
          <div class="chat-service-info">
            <div class="chat-service-img" />
            <div class="chat-service-title">
              <p class="chat-service-name">智慧社区管理小助手</p>
              <p class="chat-service-detail">实时解答社区管理相关问题</p>
            </div>
          </div>
        </div>

        <!-- 2.3 聊天内容区 -->
        <div ref="chatContainRef" class="chat-contain">
          <div 
            v-for="(msg, idx) in chatMessages" 
            :key="idx"
            :class="`chat-${msg.type}-contain`"
          >
            <p class="chat-time">{{ msg.time }}</p>
            <div 
              class="chat-text" 
              v-html="purifyHtml(marked.parse(msg.content))"
            />
          </div>

          <!-- 加载状态 -->
          <div v-if="isLoading" class="chat-loading">
            <el-loading-spinner />
            <span class="loading-text">正在思考中...</span>
          </div>

          <!-- 语音聆听状态 -->
          <div v-if="isListening" class="chat-loading">
            <el-icon class="voice-icon"><Mic /></el-icon>
            <span class="loading-text">正在聆听...</span>
          </div>
        </div>

        <!-- 2.4 聊天输入区 -->
        <div class="chat-submit">
          <el-input
            v-model="chatInput"
            type="textarea"
            placeholder="请输入您想对我说的话，按Enter发送（Shift+Enter换行）"
            @keydown="(e) => handleEnterKey(e, 'chat')"
            rows="3"
            class="chat-input-text"
          />
          <div class="chat-input-tools">
            <!-- 文件上传（Element Plus Upload） -->
            <el-upload
              action="http://localhost:5000/api/upload"
              :on-success="handleFileSuccess"
              :on-error="handleFileError"
              :before-upload="beforeFileUpload"
              class="upload-btn"
            >
              <el-button icon="Document" type="text" title="上传文件">文件</el-button>
            </el-upload>

            <!-- 语音输入 -->
            <el-button 
              icon="Mic" 
              type="text" 
              title="语音输入"
              @click="startVoiceRecognition"
            >语音</el-button>

            <!-- 功能按钮 -->
            <el-button @click="submitChat" type="primary">发送</el-button>
            <el-button @click="closeChat" type="danger">关闭</el-button>
          </div>
        </div>
      </div>

      <!-- 聊天入口按钮（关闭时显示） -->
      <div 
        v-if="!isChatOpen" 
        class="chat-support-btn"
        @click="openChat"
      >
  <el-icon class="chat-icon"><Message /></el-icon>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import { ElMessage, ElLoading } from 'element-plus'
import DOMPurify from 'dompurify'
import axios from 'axios'
// 引入Element Plus图标
import { 
  Close, Document, Mic, 
  Message, Loading 
} from '@element-plus/icons-vue'
import { marked } from 'marked'

// -------------------------- 1. 响应式数据 --------------------------
// 聊天窗口状态
const isChatOpen = ref(true)
const showSimDialog = ref(false)
const shiftDown = ref(false)
const isLoading = ref(false)
const isListening = ref(false)

// 输入内容
const chatInput = ref('')
const simInput = ref('')

// 聊天消息列表（type: you/service; content: 内容; time: 时间）
const chatMessages = ref([])

// DOM引用
const chatWindowRef = ref(null)
const chatContainRef = ref(null)

// 拖动相关状态
const dragState = ref({
  isDragging: false,
  offsetX: 0,
  offsetY: 0,
  position: { x: 100, y: 50 } // 初始位置
})

// -------------------------- 2. 初始化 --------------------------
onMounted(() => {
  // 监听Shift键状态
  window.addEventListener('keydown', handleKeyDown)
  window.addEventListener('keyup', handleKeyUp)
  // 监听窗口 resize，确保聊天内容滚动到底部
  window.addEventListener('resize', scrollToBottom)
  // 发送欢迎消息
  createInfo('service', '您好！我是智慧社区管理小助手，请问有什么可以帮助您的？')
  // 初始化聊天窗口位置
  updateChatWindowPosition()
})

onUnmounted(() => {
  window.removeEventListener('keydown', handleKeyDown)
  window.removeEventListener('keyup', handleKeyUp)
  window.removeEventListener('resize', scrollToBottom)
})

// -------------------------- 3. 拖动功能 --------------------------
const startDrag = (e) => {
  // 仅点击聊天头部时可拖动
  if (!e.target.closest('.chat-header')) return
  dragState.value.isDragging = true
  dragState.value.offsetX = e.clientX - dragState.value.position.x
  dragState.value.offsetY = e.clientY - dragState.value.position.y

  // 绑定拖动和结束事件
  document.addEventListener('mousemove', handleDrag)
  document.addEventListener('mouseup', endDrag)
}

const handleDrag = (e) => {
  if (!dragState.value.isDragging) return
  // 计算新位置（限制在可视区域内）
  const maxX = window.innerWidth - chatWindowRef.value.offsetWidth
  const maxY = window.innerHeight - chatWindowRef.value.offsetHeight
  const newX = Math.max(0, Math.min(e.clientX - dragState.value.offsetX, maxX))
  const newY = Math.max(0, Math.min(e.clientY - dragState.value.offsetY, maxY))

  dragState.value.position = { x: newX, y: newY }
  updateChatWindowPosition()
}

const endDrag = () => {
  dragState.value.isDragging = false
  document.removeEventListener('mousemove', handleDrag)
  document.removeEventListener('mouseup', endDrag)
}

const updateChatWindowPosition = () => {
  if (chatWindowRef.value) {
    chatWindowRef.value.style.left = `${dragState.value.position.x}px`
    chatWindowRef.value.style.top = `${dragState.value.position.y}px`
  }
}

// -------------------------- 4. 键盘事件处理 --------------------------
const handleKeyDown = (e) => {
  if (e.key === 'Shift') shiftDown.value = true
}

const handleKeyUp = (e) => {
  if (e.key === 'Shift') shiftDown.value = false
}

// 处理回车发送/换行
const handleEnterKey = (e, type) => {
  if (e.key !== 'Enter') return
  e.preventDefault()

  const inputRef = type === 'chat' ? chatInput : simInput
  const inputValue = inputRef.value.trim()

  if (shiftDown.value) {
    // Shift+Enter 换行
    const start = e.target.selectionStart
    const end = e.target.selectionEnd
    inputRef.value = `${inputRef.value.slice(0, start)}\n${inputRef.value.slice(end)}`
    e.target.selectionStart = e.target.selectionEnd = start + 1
  } else {
    // Enter 发送
    if (!inputValue) {
      ElMessage.warning('发送内容不能为空')
      return
    }
    if (type === 'chat') {
      submitChat()
    } else {
      handleSimSubmit()
    }
  }
}

// -------------------------- 5. 消息处理 --------------------------
// 创建消息（添加到列表并滚动到底部）
const createInfo = (type, content) => {
  const time = new Date().toLocaleTimeString()
  chatMessages.value.push({ type, content, time })
  scrollToBottom()
}

// 滚动到聊天底部
const scrollToBottom = () => {
  if (chatContainRef.value) {
    chatContainRef.value.scrollTop = chatContainRef.value.scrollHeight
  }
}

// HTML净化（防止XSS）
const purifyHtml = (html) => DOMPurify.sanitize(html)

// -------------------------- 6. 聊天功能 --------------------------
// 提交用户消息
const submitChat = () => {
  const inputValue = chatInput.value.trim()
  if (!inputValue) {
    ElMessage.warning('发送内容不能为空')
    return
  }
  // 添加用户消息
  createInfo('you', inputValue)
  // 发送请求到后端
  submityouText(inputValue)
  // 清空输入框
  chatInput.value = ''
}

// 发送请求到后端获取回复
const submityouText = async (userInput) => {
  isLoading.value = true
  try {
    const res = await axios.post('http://localhost:5000/api/chat', {
      message: userInput
    }, {
      headers: { 'Content-Type': 'application/json' }
    })
    isLoading.value = false
    if (res.data.error) {
      createInfo('service', `错误：${res.data.error}`)
    } else {
      createInfo('service', res.data.reply || '已收到您的消息，暂无明确回复')
    }
  } catch (err) {
    isLoading.value = false
    console.error('接口请求失败：', err)
    createInfo('service', '抱歉，暂时无法回复，请稍后再试')
  }
}

// -------------------------- 7. 模拟服务端消息 --------------------------
const handleSimSubmit = () => {
  const inputValue = simInput.value.trim()
  if (!inputValue) {
    ElMessage.warning('模拟消息不能为空')
    return
  }
  createInfo('service', inputValue)
  simInput.value = ''
  showSimDialog.value = false
}

const resetSimInput = () => {
  simInput.value = ''
}

// -------------------------- 8. 文件上传 --------------------------
const beforeFileUpload = (file) => {
  // 可选：限制文件类型/大小
  const fileSize = file.size / 1024 / 1024 // MB
  if (fileSize > 10) {
    ElMessage.error('文件大小不能超过10MB')
    return false
  }
  return true
}

const handleFileSuccess = (res, file) => {
  createInfo('you', `上传了文件：${file.name}`)
  if (res.error) {
    createInfo('service', `文件处理错误：${res.error}`)
  } else {
    createInfo('service', res.reply || '文件已收到并处理完成')
  }
}

const handleFileError = (err, file) => {
  createInfo('you', `上传了文件：${file.name}`)
  createInfo('service', '文件上传失败，请稍后再试')
  console.error('文件上传错误：', err)
}

// -------------------------- 9. 语音识别 --------------------------
const startVoiceRecognition = () => {
  const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition
  if (!SpeechRecognition) {
    ElMessage.error('抱歉，您的浏览器不支持语音识别（建议使用Chrome）')
    return
  }

  const recognition = new SpeechRecognition()
  recognition.lang = 'zh-CN'
  recognition.interimResults = false
  recognition.maxAlternatives = 1

  // 显示聆听状态
  isListening.value = true

  recognition.start()

  // 识别成功
  recognition.onresult = (event) => {
    isListening.value = false
    const speechResult = event.results[0][0].transcript
    createInfo('you', `语音输入：${speechResult}`)
    submityouText(speechResult)
  }

  // 识别错误
  recognition.onerror = (event) => {
    isListening.value = false
    let errorMsg = '语音识别出错'
    switch (event.error) {
      case 'not-allowed': errorMsg = '请允许麦克风权限后重试'; break
      case 'no-speech': errorMsg = '未检测到语音输入'; break
      case 'audio-capture': errorMsg = '无法访问麦克风'; break
    }
    ElMessage.error(errorMsg)
    createInfo('service', `语音识别错误：${errorMsg}`)
  }

  // 识别结束
  recognition.onend = () => {
    isListening.value = false
  }
}

// -------------------------- 10. 聊天窗口控制 --------------------------
const openChat = () => {
  isChatOpen.value = true
  updateChatWindowPosition()
}

const closeChat = () => {
  isChatOpen.value = false
}
</script>

<style scoped>
/* 整体布局 */
.chat-container {
  display: flex;
  width: 100vw;
  height: 100vh;
  box-sizing: border-box;
}

/* 左侧区域 */
.left {
  width: 30%;
  max-width: 300px;
  border: 1px solid #060;
  box-sizing: border-box;
  padding: 20px;
}

.left-content {
  color: #333;
  font-size: 16px;
}

/* 右侧区域 */
.right {
  flex: 1;
  min-width: 300px;
  position: relative;
  padding: 20px;
  box-sizing: border-box;
}

/* 聊天入口按钮 */
.chat-support-btn {
  position: fixed;
  bottom: 30px;
  right: 30px;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  background: #409eff;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  z-index: 10;
}

.chat-icon {
  font-size: 24px;
}

/* 聊天窗口 */
.chat-main {
  position: fixed;
  width: 60%;
  min-width: 500px;
  height: 80vh;
  border: 1px solid #e6e6e6;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  background: white;
  overflow: hidden;
  z-index: 100;
  transition: all 0.3s ease;
}

/* 聊天头部 */
.chat-header {
  display: flex;
  align-items: center;
  padding: 12px 16px;
  background: #f5f7fa;
  border-bottom: 1px solid #e6e6e6;
  cursor: move;
}

.close-btn {
  color: #999;
  margin-right: 12px;
}

.close-btn:hover {
  color: #666;
}

.chat-service-info {
  display: flex;
  align-items: center;
}

.chat-service-img {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: #409eff;
  margin-right: 12px;
}

.chat-service-name {
  font-size: 16px;
  font-weight: 500;
  color: #333;
  margin: 0;
}

.chat-service-detail {
  font-size: 12px;
  color: #999;
  margin: 0;
}

/* 聊天内容区 */
.chat-contain {
  width: 100%;
  height: calc(100% - 140px);
  padding: 16px;
  overflow-y: auto;
  box-sizing: border-box;
  background: #fafafa;
}

/* 消息气泡 */

.chat-you-contain,
.chat-service-contain {
  margin: 8px 0;
  padding: 10px 14px;
  border-radius: 8px;
  max-width: 80%;
  word-wrap: break-word;
  color: #222 !important;
}

.chat-you-contain {
  background: #e1f5fe;
  margin-left: auto;
}

.chat-service-contain {
  background: #f1f8e9;
  margin-right: auto;
}

.chat-time {
  font-size: 12px;
  color: #666;
  margin: 0 0 4px 0;
}

.chat-text {
  line-height: 1.6;
  font-size: 14px;
  color: #222 !important;
}

/* 加载状态 */
.chat-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px;
  color: #666;
  font-size: 14px;
}

.loading-text {
  margin-left: 8px;
}

.voice-icon {
  animation: voicePulse 1.5s infinite;
}

@keyframes voicePulse {
  0%, 100% { opacity: 0.7; }
  50% { opacity: 1; }
}

/* 聊天输入区 */
.chat-submit {
  padding: 12px 16px;
  border-top: 1px solid #e6e6e6;
  background: white;
}

.chat-input-text {
  margin-bottom: 8px;
  resize: none;
}

.chat-input-tools {
  display: flex;
  align-items: center;
  gap: 8px;
}

.upload-btn {
  margin-right: 8px;
}
</style>